package drds.server.memory.unsafe.utils.sort;

import java.io.UnsupportedEncodingException;

import drds.server.execute_engine.data_handling.Column;
import drds.server.execute_engine.data_handling.OrderByColum;
import drds.server.memory.unsafe.row.StructType;
import drds.server.memory.unsafe.row.UnsafeRow;
import drds.server.memory.unsafe.utils.BytesTools;

/**
 * Created by zagnix on 2016/6/20.
 */
public class RowPrefixComputer extends UnsafeExternalRowSorter.PrefixComputer {
	private final StructType schema;
	private final Column colMeta;

	public RowPrefixComputer(StructType schema) {
		this.schema = schema;
		/**
		 * 通过计算得到排序关键词的第一个在行的索引下标
		 */
		int orderIndex = 0;
		OrderByColum[] orderCols = schema.getOrderCols();

		if (orderCols != null) {
			for (int i = 0; i < orderCols.length; i++) {
				Column colMeta = orderCols[i].colum;
				if (colMeta.columIndex == 0) {
					orderIndex = i;
					break;
				}
			}

			this.colMeta = orderCols[orderIndex].colum;
		} else {
			this.colMeta = null;
		}
	}

	protected long computePrefix(UnsafeRow row) throws UnsupportedEncodingException {

		if (this.colMeta == null) {
			return 0;
		}

		int orderIndexType = colMeta.columType;

		byte[] rowIndexElem = null;

		if (!row.isNullAt(colMeta.columIndex)) {
			rowIndexElem = row.getBinary(colMeta.columIndex);
			;
		} else {
			rowIndexElem = new byte[1];
			rowIndexElem[0] = UnsafeRow.NULL_MARK;
		}

		/**
		 * 这里注意一下，order by 排序的第一个字段
		 */
		switch (orderIndexType) {
		case Column.COL_TYPE_INT:
		case Column.COL_TYPE_LONG:
		case Column.COL_TYPE_INT24:
			return BytesTools.getInt(rowIndexElem);
		case Column.COL_TYPE_SHORT:
			return BytesTools.getShort(rowIndexElem);
		case Column.COL_TYPE_LONGLONG:
			return BytesTools.getLong(rowIndexElem);
		case Column.COL_TYPE_FLOAT:
			return PrefixComparators.DoublePrefixComparator.computePrefix(BytesTools.getFloat(rowIndexElem));
		case Column.COL_TYPE_DOUBLE:
		case Column.COL_TYPE_DECIMAL:
		case Column.COL_TYPE_NEWDECIMAL:
			return PrefixComparators.DoublePrefixComparator.computePrefix(BytesTools.getDouble(rowIndexElem));
		case Column.COL_TYPE_DATE:
		case Column.COL_TYPE_TIMSTAMP:
		case Column.COL_TYPE_TIME:
		case Column.COL_TYPE_YEAR:
		case Column.COL_TYPE_DATETIME:
		case Column.COL_TYPE_NEWDATE:
		case Column.COL_TYPE_BIT:
		case Column.COL_TYPE_VAR_STRING:
		case Column.COL_TYPE_STRING:
			// ENUM和SET类型都是字符串，按字符串处理
		case Column.COL_TYPE_ENUM:
		case Column.COL_TYPE_SET:
			return PrefixComparators.BinaryPrefixComparator.computePrefix(rowIndexElem);
			// BLOB相关类型和GEOMETRY类型不支持排序，略掉
		}
		return 0;
	}
}
